Excel BI - Excel Challenge 805

excel-challenges
excel-formulas
🔰 List the Rivers which contain at least 2 distinct vowels and vowels are either in increasing order (>=) or decreasing order (<=) but not
Published

March 24, 2026

Illustration for Excel BI - Excel Challenge 805

Challenge Description

🔰 List the Rivers which contain at least 2 distinct vowels and vowels are either in increasing order (>=) or decreasing order (<=) but not

Solutions

library(tidyverse)
library(readxl)

path = "Excel/800-899/805/805 Vowels in Increasing or Decreasing Order.xlsx"
input = read_excel(path, range = "A2:B16")
test  = read_excel(path, range = "D2:G5")

vowel_factor = factor(c("a", "e", "i", "o", "u"),
                      levels = c("a", "e", "i", "o", "u"),
                      ordered = TRUE)

result = input %>%
  mutate(
    vowels = str_extract_all(str_to_lower(Rivers), "[aeiou]"),
    ord = map_chr(vowels, ~ {
      d = diff(match(.x, levels(vowel_factor)))
      if (all(d >= 0) & any(d > 0)) "increasing"
      else if (all(d <= 0) & any(d < 0)) "decreasing"
      else "neither"
    })
  ) %>%
  filter(ord != "neither") %>%
  select(Group, Rivers) %>%
  arrange(Group, Rivers) %>%
  mutate(rn = row_number(), .by = Group) %>%
  pivot_wider(names_from = rn, names_glue = "River{rn}" , values_from = Rivers)

all.equal(result, test, check.attributes = FALSE)
# [1] TRUE
  • Logic: Read the workbook ranges needed for the challenge; Derive the required intermediate columns; Parse the packed text or string structure; Aggregate or rank the data at the required grouping level.
  • Strengths: The solution stays close to the text pattern itself, which makes the extraction logic easy to audit.
  • Areas for Improvement: The solution assumes the workbook layout and selected ranges remain stable, so any structural change in the sheet would require small adjustments.
  • Gem: A small number of well-targeted text patterns does most of the heavy lifting.
import pandas as pd
import numpy as np
import re

path = "800-899/805/805 Vowels in Increasing or Decreasing Order.xlsx"
input = pd.read_excel(path, usecols="A:B", skiprows=1, nrows=15)
test = pd.read_excel(path, usecols="D:G", skiprows=1, nrows=3).rename(columns=lambda col: col.replace('.1', ''))

vowel_levels = ['a', 'e', 'i', 'o', 'u']
vowel_map = {v: i for i, v in enumerate(vowel_levels)}

input['riv'] = input['Rivers'].str.lower()
input['vowels'] = input['riv'].apply(lambda s: re.findall(r'[aeiou]', s))
input['inc'] = input['vowels'].apply(lambda v: all(np.diff([vowel_map[x] for x in v]) >= 0)) 
input['dec'] = input['vowels'].apply(lambda v: all(np.diff([vowel_map[x] for x in v]) <= 0))
input['vowel_order'] = np.select(
    [input['inc'] & ~input['dec'], ~input['inc'] & input['dec']],
    ['increase', 'decrease'],
    default='neither'
)

filtered = input[input['vowel_order'] != 'neither'].copy()
filtered = filtered[['Group', 'Rivers']].sort_values(['Group', 'Rivers'])

filtered['rn'] = filtered.groupby('Group').cumcount() + 1

result = filtered.pivot(index='Group', columns='rn', values='Rivers')
result.columns = [f"River{col}" for col in result.columns]
result = result.reset_index()
print(result.equals(test)) # True

The Python version follows the same grouped logic and keeps the transformation explicit in a dataframe pipeline.

Difficulty Level

Medium

The individual steps are manageable, but the correct transformation pattern is not obvious from the raw data.